package com.liuyc.lib.common.mvvm.view

import androidx.annotation.LayoutRes
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentTransaction
import com.liuyc.lib.common.mvvm.vm.BaseViewModel

/**********************************************************
 * 摘 要： [只会显示一个 fragment 的activity]
 * 初始版本：1.0.0
 * @author liujun
 * 创建日期： 2019/1/21
 */
abstract class ShowOneFragmentActivity<VM: BaseViewModel>(@LayoutRes layoutResID: Int) : ViewBaseActivity<VM>(layoutResID) {
    protected var currentShowFragment: Fragment? = null
        private set

    /**
     * 将fragment添加到事务中，但是不显示
     *
     * @param tag
     * @param createFragmentParameters
     * @return
     */
    protected fun addFragment(tag: String, createFragmentParameters: Any? = null) {
        if (currentShowFragment != null && currentShowFragment!!.tag != null && currentShowFragment!!.tag == tag) {
            return
        }
        var fragment = findFragmentByTag(tag)
        if (fragment == null) {
            val fragmentTransaction = supportFragmentManager.beginTransaction()
            fragment = createFragment(tag, createFragmentParameters)
            val replayLayoutId = replayLayoutId()
            check(replayLayoutId != 0) { "未找到fragment替换的布局" }
            fragmentTransaction.add(replayLayoutId, fragment!!, tag)
            if (currentShowFragment !== fragment) {
                fragmentTransaction.hide(fragment)
            }
            fragmentTransaction.commitAllowingStateLoss()
        }
    }

    /**
     * 获取 fragment 如果在缓存中找到fragment 则会触发 resetFragmentParameters 方法需要上层自行处理
     *
     * @param tag
     * @param createFragmentParameters
     * @return
     */
    protected fun showFragment(tag: String, createFragmentParameters: Any? = null): Fragment? {
        val fragmentTransaction = supportFragmentManager.beginTransaction()
        var fragment = getFragmentByCache(tag, fragmentTransaction)
        if (fragment == null) {
            fragment = createFragment(tag, createFragmentParameters)
            val replayLayoutId = replayLayoutId()
            check(replayLayoutId != 0) { "未找到fragment替换的布局" }
            fragmentTransaction.add(replayLayoutId, fragment!!, tag).show(fragment!!)
            fragmentTransaction.addToBackStack(tag)
        } else {
            resetFragmentParameters(fragment, createFragmentParameters)
            fragmentTransaction.show(fragment)
        }
        fragmentTransaction.commitAllowingStateLoss()
        currentShowFragment = fragment
        return fragment
    }

    /**
     * 根据传入的tag 获取fragment
     *
     * @param tag
     * @return
     */
    private fun getFragmentByCache(tag: String?, fragmentTransaction: FragmentTransaction): Fragment? {
        var fragment: Fragment? = null
        val fragmentList = supportFragmentManager.fragments
        if (fragmentList == null || fragmentList.size == 0 || tag == null || tag.trim { it <= ' ' }.length == 0) {
            return fragment
        }
        for (f in fragmentList) {
            if (f == null) {
                continue
            }
            if (tag == f.tag) {
                fragment = f
            } else {
                fragmentTransaction.hide(f)
            }
        }
        return fragment
    }

    protected fun findFragmentByTag(tag: String?): Fragment? {
        return supportFragmentManager.findFragmentByTag(tag)
    }

    protected abstract fun resetFragmentParameters(fragment: Fragment?, createFragmentParameters: Any?)
    protected abstract fun replayLayoutId(): Int
    protected abstract fun createFragment(tag: String, createFragmentParameters: Any?): Fragment?
}